//
//  PassengerRepository.m
//  WebPDA
//
//  Created by Justin Yip on 8/5/10.
//  Copyright 2010 TenNights.com. All rights reserved.
//

#import "PassengerRepository.h"
#import <sqlite3.h>
#import "AppDelegate_Shared.h"
#import "Passenger.h"


@implementation PassengerRepository

@synthesize rowArray;
@synthesize database;

//单例
static PassengerRepository *sharedRepository = nil;

+(PassengerRepository*)sharedRepository{
	@synchronized(self){
		if (nil == sharedRepository) {
			sharedRepository = [[self alloc] init];
		}
	}
	return sharedRepository;
}

-(id)init {
	if (self = [super init]) {
		//取数据库路径
		NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
		NSString *documentsDirectory = [paths objectAtIndex:0];
		NSString *dbname = [documentsDirectory stringByAppendingPathComponent:@"WebPDA.sqlite"];
		NSLog(@"open sqlite db:%@",dbname);
		
		//打开数据库
		int returnCode = sqlite3_open([dbname UTF8String], &database);
		if (returnCode != SQLITE_OK) {
			NSLog(@"error open database[%d], message: %s", returnCode, sqlite3_errmsg(database));
			sqlite3_close(database);
			abort();
		}
		
		//初始化缓存
		cache = [[NSMutableDictionary alloc] initWithCapacity:5];
	}
	return self;
}

///////////////////////query methods//////////////////////////////

-(Passenger*)passengerInRow:(NSUInteger)row atColumn:(NSUInteger)column {
	
	NSString *acture_row = [[self getRows] objectAtIndex:row];
	
	//根据行取缓存
	NSArray *cached_row = [cache objectForKey:acture_row];
	if (cached_row) {
		
		//NSLog(@"fetch from cache");
		return [cached_row objectAtIndex:column];
		
	}else {
		
		//NSLog(@"fetch from core data");
		//fetch data in row [row-1,row+1,row+1], and cache it
		
		AppDelegate_Shared *appDelegate = (AppDelegate_Shared*)[UIApplication sharedApplication].delegate;
		
		NSFetchRequest *request = [[NSFetchRequest alloc] init];
		
		//entity
		NSEntityDescription *entity = [NSEntityDescription entityForName:@"Passenger" inManagedObjectContext:appDelegate.managedObjectContext];
		[request setEntity:entity];
		
		//predicate
		NSPredicate *predicate = [NSPredicate predicateWithFormat:@"row = %@", acture_row];
		[request setPredicate:predicate];
		
		NSError *error;
		NSArray *result_objects = [appDelegate.managedObjectContext executeFetchRequest:request error:&error];
		
		//缓存
		[cache setValue:result_objects forKey:acture_row];
		
		[request release];
		
		return [result_objects objectAtIndex:column];
		
	}
	
	/*
	const char *sql = [@"select * from ZPASSENGER where ZROW in(?,?,?) order by ZROW asc" UTF8String];
	sqlite3_stmt *stmt = NULL;
	int returnCode = sqlite3_prepare_v2(database, sql, -1, &stmt, NULL);
	if (returnCode != SQLITE_OK) {
		NSLog(@"error prepare statemet,return:%d,%s",returnCode, sqlite3_errmsg(database));
		if(stmt){sqlite3_finalize(stmt);}
		sqlite3_close(database);
		abort();
	}
	sqlite3_bind_int(stmt, 1, row-1);
	sqlite3_bind_int(stmt, 2, row);
	sqlite3_bind_int(stmt, 3, row+1);
	
	//收集数据
	NSMutableArray *tmpArray = [[NSMutableArray alloc] init];
	int return_code;
	while(SQLITE_DONE != (return_code = sqlite3_step(stmt))){
		//转换成对象
		for (int i=0; i<sqlite3_column_count(stmt); i++) {
			const char* column_name = sqlite3_column_name(stmt, i);
			sqlite3_value *value = sqlite3_column_value(stmt, i);
			Passenger *p = [[Passenger alloc] init];
			//from database column name to object property
			NSString *property_name = [[[NSString stringWithCString:column_name encoding:NSUTF8StringEncoding] substringFromIndex:1] lowercaseString];
			NSString *property_setter = [NSString stringWithFormat:@"set%@:", [property_name capitalizedString]];
			NSLog(@"setter:%@",property_setter);
			if ([p respondsToSelector:@selector(property_setter)]) {
				NSLog(@"respond");
			}
		}
	}
	//cache it
	[tmpArray release];*/
}

-(NSUInteger)numberOfPassengerInRow:(NSUInteger)row {
	
	//执行
	const char *sql = [@"select count(*) from ZPASSENGER where ZROW = ?" UTF8String];
	sqlite3_stmt *stmt = NULL;
	int returnCode = sqlite3_prepare_v2(database, sql, -1, &stmt, NULL);
	if (returnCode != SQLITE_OK) {
		NSLog(@"error prepare statemet,return:%d,%s",returnCode, sqlite3_errmsg(database));
		if(stmt){sqlite3_finalize(stmt);}
		sqlite3_close(database);
		abort();
	}
	sqlite3_bind_int(stmt, 1, row);
	sqlite3_step(stmt);
	int count = sqlite3_column_int(stmt, 0);
		
	//释放
	sqlite3_finalize(stmt);
	
	return count;
}

-(NSArray*)getRows {
	
	if (nil != rowArray) {
		return rowArray;
	}
	
	//执行
	const char *sql = [@"select distinct(zrow) from zpassenger asc" UTF8String];
	sqlite3_stmt *stmt = NULL;
	int returnCode = sqlite3_prepare_v2(database, sql, -1, &stmt, NULL);
	if (returnCode != SQLITE_OK) {
		NSLog(@"error prepare statemet,return:%d",returnCode);
		if(stmt){sqlite3_finalize(stmt);}
		sqlite3_close(database);
		abort();
	}
	
	//收集数据
	NSMutableArray *tmpArray = [[NSMutableArray alloc] init];
	while(SQLITE_DONE != sqlite3_step(stmt)){
		int seatRow = sqlite3_column_int(stmt, 0);
		[tmpArray addObject:[NSString stringWithFormat:@"%d", seatRow]];
	}
	self.rowArray = tmpArray;
	[tmpArray release];
	
	//释放
	sqlite3_finalize(stmt);
	
	return rowArray;
	
	/*
	 AppDelegate_Shared *appDelegate = (AppDelegate_Shared*)[UIApplication sharedApplication].delegate;
	 
	 NSFetchRequest *request = [[NSFetchRequest alloc] init];
	 
	 //entity
	 NSEntityDescription *entity = [NSEntityDescription entityForName:@"Passenger" inManagedObjectContext:appDelegate.managedObjectContext];
	 [request setEntity:entity];
	 
	 [request setResultType:NSDictionaryResultType];
	 
	 NSExpression *keyPathExp = [NSExpression expressionForKeyPath:@"row"];
	 
	 NSExpressionDescription *expDesc = [[[NSExpressionDescription alloc] init] autorelease];
	 [expDesc setName:@"rows"];
	 [expDesc setExpression:keyPathExp];
	 [expDesc setExpressionResultType:NSDecimalAttributeType];
	 [request setPropertiesToFetch:[NSArray arrayWithObject:expDesc]];*/
}

/*
-(NSUInteger)getMaxRows {
	AppDelegate_Shared *appDelegate = (AppDelegate_Shared*)[UIApplication sharedApplication].delegate;
	
	NSFetchRequest *request = [[NSFetchRequest alloc] init];
	
	//entity
	NSEntityDescription *entity = [NSEntityDescription entityForName:@"Passenger" inManagedObjectContext:appDelegate.managedObjectContext];
	[request setEntity:entity];
	
	[request setResultType:NSDictionaryResultType];
	//predicate
	//NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name like %"];
	//[request setPredicate:predicate];
	
	//select max row
	NSExpression *keyPathExp = [NSExpression expressionForKeyPath:@"row"];
	NSExpression *maxRowExp = [NSExpression expressionForFunction:@"max:" arguments:[NSArray arrayWithObject:keyPathExp]];
	
	NSExpressionDescription *expDesc = [[[NSExpressionDescription alloc] init] autorelease];
	[expDesc setName:@"maxRow"];
	[expDesc setExpression:maxRowExp];
	[expDesc setExpressionResultType:NSDecimalAttributeType];
	[request setPropertiesToFetch:[NSArray arrayWithObject:expDesc]];
	
	NSError *error;
	NSArray *objects = [appDelegate.managedObjectContext executeFetchRequest:request error:&error];
	if ([objects count] > 0) {
		NSLog(@"max row: %@", [[objects objectAtIndex:0] valueForKey:@"maxRow"]);
	}
	
	[request release];
	
	return 0;
}*/

-(void)dealloc {
	sqlite3_close(database);
	[rowArray release];
	[cache release];
	[super dealloc];
}

@end
